package com.example.userserver.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.commons.config.JwtConfigTime;
import com.example.commons.entity.UserDO;
import com.example.commons.utils.*;
import com.example.commons.vo.TokenVO;
import com.example.userserver.config.RedisUtil;
import com.example.userserver.dao.UserSerDao;
import com.example.userserver.service.MpConfigService;
import com.example.userserver.service.UserRoleService;
import com.example.userserver.service.UserService;
import com.example.userserver.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

@Service
@Slf4j
public class UserUserServiceImpl extends ServiceImpl<UserSerDao, UserDO> implements UserService {

    private static final String T_REG_SMS_PREFIX = "TRAINING_REG_";//培训端
    private static final String C_REG_SMS_PREFIX = "CERTIFICATE_REG_";//证书端
    private static final String O_REG_SMS_PREFIX = "ORTHER_REG_";//其他端

    //授权（必填）
    String grant_type = DataEnum.wx_grant_type.getValue();

    //微信url
    String wx_url = DataEnum.wx_authorization_url.getValue();

    @Autowired
    private UserService userService;
    @Autowired
    private UserSerDao userSerDao;
    @Autowired
    private MpConfigService mpConfigService;
    @Autowired
    private UserRoleService userRoleService;
    @Resource
    private RedisUtil redisUtil;
    @Override
    public List<UserDO> list() {
        return userSerDao.list();
    }


    @Override
    public List<UserDO> list1(Map map) {
        //1 根据课程id查询课程里面所有的章节
        QueryWrapper<UserDO> wrapperChapter = new QueryWrapper<>();

        wrapperChapter.like("name","admin");
        wrapperChapter.last("limit 10");
        List<UserDO> eduChapterList = baseMapper.selectList(wrapperChapter);

        return eduChapterList;
    }
    @Override
    public UserDO getByUserId(Long userId) {
        return baseMapper.selectById(userId);
    }
    @Override
    public Object login(Map member) {
        String wxId = member.get("wxId").toString();
        String encryptedData =member.get("encryptedData").toString();
        String iv =member.get("iv").toString();
        String code =member.get("code").toString();
        //Integer wxId, String encryptedData, String iv, String code
        if(member.size()==0){
            throw new JinZhiException(ExceptionEnum.INVALID_PARAM_ERROR.getStatus(),ExceptionEnum.INVALID_PARAM_ERROR.getMessage());
        }

        //调用微信接口获取信息 解析相应内容（转换成json对象）
        JSONObject json = JSONObject.parseObject(wxurl(wxId,code));
        String errCode = null;
        if (null != json.get("errcode")) {
            errCode = json.get("errcode").toString();
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(errCode)) {
            String errMsg = json.getString("errmsg");
            throw new JinZhiException(ExceptionEnum.WX_ERROR_CODE.getStatus(),ExceptionEnum.WX_ERROR_CODE.getMessage()+ errMsg);
        }
        //获取会话密钥（session_key）
        String session_key = json.getString("session_key");
        //用户的唯一标识（openid）
        String openid = json.getString("openid");
        Map<String, Object> map = new HashMap<>();

        try {
          //  URLEncoder.encode(encryptData,"UTF-8").replace("%3D","=").replace("%2F","/")
            String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8").replace("%3D","=").replace("%2F","/");
            JSONObject object = JSONObject.parseObject(result);
            // 拿到手机号码
            String mobile = object.getString("phoneNumber");
            if (StringUtils.isNotBlank(mobile)) {
                /////////////// 2、根据手机号码查询判断用户是否存在 ////////////////
                log.info("openId:{}", openid);
                UserDO userDO = new UserDO();
                QueryWrapper<UserDO> wrapper=new QueryWrapper<>();
                wrapper.eq("mobile",mobile);
            //    List<UserDO> userDOS = userSerDao.list(wrapper);
                List<UserDO> userDOS =  userService.list(wrapper);
                if (userDOS != null&&userDOS.size()>0) {
                    userDO = userDOS.get(0);
                    List<Long> roleIds = userRoleService.listRoleId(userDOS.get(0).getId());

                    if (roleIds != null && roleIds.size() > 0) {
                        userDOS.get(0).setRoleIds(roleIds);
                    } else {
                        List<Long> list = new ArrayList<>();
                        list.add(56L);
                        userDOS.get(0).setRoleIds(list);
                    }

                    if (wxId.equals(101)) {
                        userDOS.get(0).setCerOpenId(openid);//证书小程序openId
                    } else if (wxId.equals(102)) {
                        userDOS.get(0).setTraOpenId(openid);//培训小程序openId
                    }
                    userSerDao.updateById(userDOS.get(0));
                } else {
                    userDO.setUsername(mobile);//默认存入手机号码
                    userDO.setWxId(Integer.valueOf(wxId));
                    if (wxId.equals(101)) {
                        userDO.setCerOpenId(openid);//证书小程序openId
                    } else if (wxId.equals(102)) {
                        userDO.setTraOpenId(openid);//培训小程序openId
                    }
                    userDO.setMobile(mobile);
                    userDO.setType(0);//默认个人会员
                    String password = "123456";
                    String salt = UUIDUtils.get();
                    String encodePasswd = PasswdUtils.get(password, salt);
                    userDO.setSalt(salt);
                    userDO.setPassword(encodePasswd);
                    userDO.setMoney(BigDecimal.valueOf(0.0));//默认0元
                    userDO.setGmtCreate(new Date());
                    userDO.setGmtModified(userDO.getGmtCreate());
                    userDO.setStatus(1);//默认正常
                    userDO.setSex(0L);//默认未知

                    List<Long> list = new ArrayList<>();
                    list.add(56L);
                    userDO.setRoleIds(list);

                    userSerDao.insert(userDO);
                }

                /////////////// 3、生成自定义登录态(jwt token) ////////////////
                //生成,根据openid
                String token = getToken(mobile);

                ///////////////  4、将生成自定义登录态与session_key、openid进行关联 ////////////////
                Map cache = new HashMap();
                cache.put("session_key", session_key);
                cache.put("mobile", mobile);
                EhCacheUtil.put(token, cache);

                /////////////// 5、返回自定义登录态token + 用户信息////////////////
                map.put("isOpenId",true);//20200701 pjr新增isOpenId
                map.put("token", token);
                map.put("userId", userDO.getId());
                map.put("userName", userDO.getUsername());
                map.put("mobile", userDO.getMobile());
                map.put("headPortrait", userDO.getHeadPortrait());
                //登录成功之后，生成token字符串，使用jwt工具类
              //  String jwtToken = JwtUtils.getJwtToken(userDO.getId().toString(), userDO.getId().toString());

            } else {
              //  return ApiResult.fail(ApiEnumError.USER_NOT_MOBILE.getCodeStr());
                throw new JinZhiException(ExceptionEnum.INVALID_PHONE_NULL.getStatus(),ExceptionEnum.INVALID_PHONE_NULL.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new JinZhiException(ExceptionEnum.TRY_CATH_ERROY.getStatus(),ExceptionEnum.TRY_CATH_ERROY.getMessage());
        }


        return map;
    }

    @Override
    public Long userPhone(String phone) {
        return baseMapper.userPhone(phone);
    }

    @Override
    public String getToken(String mobile) {
        QueryWrapper<UserDO> wrapper=new QueryWrapper();
        wrapper.like("mobile",mobile);
       List<UserDO>  userDO = userService.list(wrapper);
        if (userDO.size()==0) {
            throw new JinZhiException(ApiEnumError.apiAuthorizationWxLoginFailed.getCode(),ApiEnumError.apiAuthorizationWxLoginFailed.getMsg());
        }
        //将用户信息储存到redis里面
       // redisUtil.set(token,userDO.getId(), RedisTime.redisTimeDay);

        return createToken(userDO.get(0));
    }

    private String createToken(UserDO userDO) {
        TokenVO vo = new TokenVO();
        String token = JWTUtil.jzSign(userDO, JwtConfigTime.JwtVerify, JwtConfigTime.time5.longValue());
        //String refreshToken = JWTUtil.sign(userDO.getId() + "", userDO.getId() + userDO.getMobile(), 2l, true);
        vo.setToken(token);
        vo.setRefleshToken(token);
        vo.setTokenExpire(2l);
        vo.setRefreshTokenExpire(7l);
        return vo.getToken();
    }


    @Override
    public UserDO getUserMobile(Long mobile) {
        return baseMapper.getUserMobile(mobile);
    }

    @Override
    public UserDO getUserInfo(String token) {
        String userid=  redisUtil.get(token).toString();;
        //查询数据库根据用户id获取用户数据
        UserDO member = userService.getById(userid);
        return member;
    }


    public String wxurl(String wxId,String code){

        MpConfigDO mpConfigDO = mpConfigService.getById(wxId);
        //获取登录手机号和密码
        String params = "appid=" + mpConfigDO.getAppId() + "&secret=" + mpConfigDO.getAppSecret() + "&js_code=" + code + "&grant_type=" + grant_type;
        //发送请求
        String sr = HttpRequest.sendGet(wx_url, params);
        return sr;
    }
}
